﻿using System;
using System.IO;
using System.Windows.Forms;
using System.Data.SqlServerCe;
using Finance.Controllers;
using Finance.Data;
using Finance.Data.Entities;
using Finance.GUI;
using Finance.Properties;
using Finance.ViewModels;
using Finance.Views;

namespace Finance
{
	static class Program
	{
		public static FinanceDataBase DataBase;

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[MTAThread]
		static void Main()
		{
			try
			{
				DataBase = new FinanceDataBase();
				var dataBaseFullPath = 
					Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "DataBase\\finance.sdf");
				DataBase.OpenConnection(dataBaseFullPath);
			}
			catch (SqlCeException sqlException)
			{
				MessageBox.Show(Resources.DataBaseConnectionError + sqlException);
				return;
			}
			catch (Exception exception)
			{
				MessageBox.Show(Resources.DataBaseConnectionError + exception);
				return;
			}

			try
			{
				Action<Exception> exceptionHandler =
				exception => MessageBox.Show(Resources.FormDayFinance_UpdateDataGrid_DataSourceError + exception.Message);

				var mainForm = new FormDayFinance
					{
						DataBase = DataBase,
						DayDocumentsViewModel = new DayDocumentsViewModel(
							DataBase, 
							exceptionHandler,
							EditNote,
							EditDocument)
					};

				Application.Run(mainForm);
			}
			finally
			{
				DataBase.Dispose();	
			}
		}

		static bool EditNote(Note note)
		{
			using (var form = new FormOkCancel())
			{
				var noteControl = new NoteView {Note = note};
				form.Controls.Add(noteControl);
				form.OnApply += (sender, args) => noteControl.Apply();

				return form.ShowDialog() == DialogResult.OK;
			}
		}

		private static bool EditDocument(IDocumentBase document)
		{
			Control control;
			Func<bool> apply;

			var debtDocument = document as IDebtDocument;
			if (debtDocument != null)
			{
				var debtDocumentControl = new DebtDocumentControl {
					ViewModel = new DebtDocumentViewModel(debtDocument, new DocumentBaseController(DataBase))
				};

				apply = debtDocumentControl.Apply;
				control = debtDocumentControl;
			}
			else if (document is IRepayDebtDocument)
			{
				var repayDebtDocumentControl = new RepayDebtDocumentControl
				{
					ViewModel = new RepayDebtDocumentViewModel(
						(IRepayDebtDocument)document, 
						new RepayDebtDocumentController(DataBase))
				};

				apply = repayDebtDocumentControl.Apply;
				control = repayDebtDocumentControl;
			}
			else
			{
				var documentControl = new DocumentControl{
					DocumentViewModel = new DocumentViewModel(document, new DocumentController(DataBase))
				};

				apply = documentControl.Apply;
				control = documentControl;
			}

			using (var formDocument = new FormDocument {Control = control})
			{
				formDocument.OnApply += (sender, args) => {
						args.IsDataValid = apply();
					};
				return formDocument.ShowDialog() == DialogResult.OK;
			}
		}

		public static string GetDocumentTypeName(DocumentType documentType)
		{
			switch (documentType)
			{
				case DocumentType.Dohod:
					return Resources.DocumentType_Income;
				case DocumentType.Rashod:
					return Resources.DocumentType_Expense;
				case DocumentType.DohodZaimBack:
					return Resources.DocumentType_IncomeCreditBack;
				case DocumentType.DohodZaim:
					return Resources.DocumentType_IncomeCreditGet;
				case DocumentType.RashodZaimBack:
					return Resources.DocumentType_ExpenseCreditBack;
				case DocumentType.RashodZaim:
					return Resources.DocumentType_ExpenseCreditGive;
				default:
					throw new Exception("Invalid document type");
			}
		}
	}
}